package org.clockworkmages.games.anno1186.gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.ToolTipManager;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import javax.swing.text.StyledDocument;

import org.clockworkmages.games.anno1186.GameBeansContext;
import org.clockworkmages.games.anno1186.controllers.LocalMapMovementController;
import org.clockworkmages.games.anno1186.dao.FileUtil;
import org.clockworkmages.games.anno1186.model.option.Option;

/**
 * Collection of GUI elements for the default game screen.
 */
public class LocalExplorationPanel
		extends JPanel {

	private MainTextPanel textPane;
	private InfoTextPane statsPanel;
	private JList<Option> optionList;
	private JTextField optionTextInput;
	private OptionTextInputKeyListener optionTextInputKeyListener;
	// private JPanel optionCardPanel;
	private TotemPanel leftTotemPanel;
	private TotemPanel rightTotemPanel;
	private LocalMapPanel localMapPanel;

	public LocalExplorationPanel() {

		this.setFocusable(true);
		this.requestFocusInWindow();

		this.setLayout(new BorderLayout());
		this.setPreferredSize(new Dimension(650, 605));
		// JButton optionsbutton = new JButton("Options");
		// add(optionsbutton, BorderLayout.PAGE_START);

		final Image sunImage = FileUtil.getResourceAsImage("images/sun.png");
		final Image moonImage = FileUtil.getResourceAsImage("images/moon.png");

		textPane = new MainTextPanel(sunImage, moonImage);
		StyledDocument doc = textPane.getStyledDocument();
		textPane.setEditable(false);

		JScrollPane scrollPane = new JScrollPane(textPane);
		scrollPane.setPreferredSize(new Dimension(450, 450));
		scrollPane.setOpaque(true);
		scrollPane.setBorder(null);

		JPanel statsTotemsOptionsPanel = new JPanel();
		statsTotemsOptionsPanel.setLayout(new BorderLayout());
		statsTotemsOptionsPanel.setPreferredSize(new Dimension(180, 700));
		add(statsTotemsOptionsPanel, BorderLayout.EAST);

		// final Image guiBottomImage = FileUtil
		// .getResourceAsImage("images/gui_bottom.png");
		// JPanel bottomPanel = new JPanel() {
		// @Override
		// public void paintComponent(final Graphics g) {
		// super.paintComponent(g);
		// g.drawImage(guiBottomImage, 0, 0, null);
		// }
		// };
		// bottomPanel.setLayout(new BorderLayout());
		// add(bottomPanel, BorderLayout.PAGE_END);

		localMapPanel = new LocalMapPanel();
		// localMapPanel.setPreferredSize(new Dimension(270, 220));
		// mapStatsOptionsPanel.add(localMapPanel, BorderLayout.CENTER);

		final Image totemImage = FileUtil
				.getResourceAsImage("images/totem.png");

		leftTotemPanel = new TotemPanel(totemImage);
		leftTotemPanel.setPreferredSize(new Dimension(50, 450));
		statsTotemsOptionsPanel.add(leftTotemPanel, BorderLayout.WEST);
		leftTotemPanel.getTotemImage().setTargetState(0, 1000);

		rightTotemPanel = new TotemPanel(totemImage);
		rightTotemPanel.setPreferredSize(new Dimension(50, 450));
		statsTotemsOptionsPanel.add(rightTotemPanel, BorderLayout.EAST);
		rightTotemPanel.getTotemImage().setTargetState(0, 1000);

		statsPanel = new StatsInfoTextPane();
		statsPanel.setPreferredSize(new Dimension(180, 155));
		statsTotemsOptionsPanel.add(statsPanel, BorderLayout.CENTER);
		GameBeansContext.register(statsPanel);

		GeneralOptionsPanel generalOptionsPanel = new GeneralOptionsPanel();
		generalOptionsPanel.setPreferredSize(new Dimension(180, 155));
		statsTotemsOptionsPanel.add(generalOptionsPanel, BorderLayout.PAGE_END);

		// Options panel:

		ToolTipManager toolTipManager = ToolTipManager.sharedInstance();

		// optionCardPanel = new JPanel(new CardLayout());
		// optionCardPanel.setOpaque(false);
		// optionCardPanel.setPreferredSize(new Dimension(450, 155));
		// bottomPanel.add(optionCardPanel, BorderLayout.CENTER);

		// JPanel textOptionPanel = new JPanel();
		// textOptionPanel.setOpaque(false);
		// textOptionPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
		// optionCardPanel.add(textOptionPanel,
		// GameUiConstants.OPTION_PANEL_TEXT_CARD);

		OptionTextInputKeyListener optionTextInputKeyListener = new OptionTextInputKeyListener();

		optionTextInput = new JTextField(10);
		optionTextInput.setMaximumSize(new Dimension(100, 25));
		optionTextInput.addKeyListener(optionTextInputKeyListener);
		// textOptionPanel.add(optionTextInput);

		optionList = new JList<Option>() {
			@Override
			public String getToolTipText(MouseEvent event) {
				Point p = event.getPoint();
				int location = locationToIndex(p);
				if (location > -1) {
					String tip = ((Option) getModel().getElementAt(location))
							.getTooltip();
					return tip;
				}
				return "";
			}
		};
		optionList.setOpaque(false);
		((JLabel) optionList.getCellRenderer()).setOpaque(false);
		optionList.setCellRenderer(new OptionListCellRenderer());
		optionList.addListSelectionListener(new ListSelectionListener() {
			@Override
			public void valueChanged(ListSelectionEvent arg0) {
				if (!arg0.getValueIsAdjusting()) {
					Option selectedOption = optionList.getSelectedValue();
					if (selectedOption != null) {
						selectedOption.select();
					}
				}
			}
		});
		toolTipManager.registerComponent(optionList);

		// JPanel listOptionPanel = new JPanel();
		// listOptionPanel.setOpaque(false);
		// listOptionPanel.setLayout(new GridLayout(1, 1));
		// listOptionPanel.add(optionList);
		// optionCardPanel.add(listOptionPanel,
		// GameUiConstants.OPTION_PANEL_LIST_CARD);

		// ((CardLayout) optionCardPanel.getLayout()).show(optionCardPanel,
		// "listOption");

		final LocalMapMovementController mapMovementController = GameBeansContext
				.getBean(LocalMapMovementController.class);

		Action processMove = new AbstractAction() {
			public void actionPerformed(ActionEvent e) {
				mapMovementController.move(e.getActionCommand());
			}
		};
		getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
				KeyStroke.getKeyStroke('w'), "processMove");
		getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
				KeyStroke.getKeyStroke('d'), "processMove");
		getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
				KeyStroke.getKeyStroke('s'), "processMove");
		getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
				KeyStroke.getKeyStroke('a'), "processMove");
		getActionMap().put("processMove", processMove);

		addStylesToDocument(doc);

		JLayeredPane textAndMapPanel = new JLayeredPane();
		textAndMapPanel.setBounds(0, 0, 600, 400);
		textAndMapPanel.setPreferredSize(new Dimension(300, 310));
		localMapPanel.setBounds(0, 0, 300, 300);
		textAndMapPanel.add(localMapPanel, Integer.valueOf(2), 0);
		scrollPane.setBounds(100, 100, 300, 300);
		textAndMapPanel.add(scrollPane, Integer.valueOf(3), 0);

		// JPanel textAndMapPanel = new JPanel();
		// textAndMapPanel.setLayout(new BorderLayout());
		// textAndMapPanel.add(scrollPane, BorderLayout.PAGE_START);
		// textAndMapPanel.add(localMapPanel, BorderLayout.PAGE_END);

		add(textAndMapPanel, BorderLayout.WEST);
	}

	protected void addStylesToDocument(StyledDocument doc) {
		// Initialize some styles.
		Style def = StyleContext.getDefaultStyleContext().getStyle(
				StyleContext.DEFAULT_STYLE);

		Style regular = doc.addStyle(FontStyleConstants.REGULAR, def);
		StyleConstants.setFontFamily(def, "SansSerif");

		Style s = doc.addStyle(FontStyleConstants.ITALIC, regular);
		StyleConstants.setItalic(s, true);

		s = doc.addStyle(FontStyleConstants.BOLD, regular);
		StyleConstants.setBold(s, true);

		s = doc.addStyle(FontStyleConstants.RED_BOLD, regular);
		StyleConstants.setBold(s, true);
		StyleConstants.setForeground(s, Color.RED);

		s = doc.addStyle(FontStyleConstants.LARGE, regular);
		StyleConstants.setFontSize(s, 16);

		// option list:
		s = doc.addStyle(FontStyleConstants.OPTIONLIST, regular);
		StyleConstants.setFontSize(s, 16);

		Box optionListBox = Box.createVerticalBox();
		optionListBox.add(optionList);
		optionListBox.setBorder(BorderFactory.createEmptyBorder(0, 0, 6, 0));
		StyleConstants.setComponent(s, optionListBox);

		// text input:
		s = doc.addStyle(FontStyleConstants.TEXTINPUT, regular);
		StyleConstants.setFontSize(s, 16);

		Box textInputBox = Box.createVerticalBox();
		textInputBox.add(optionTextInput);
		textInputBox.setBorder(BorderFactory.createEmptyBorder(0, 0, 6, 0));
		StyleConstants.setComponent(s, textInputBox);
	}

	public MainTextPanel getTextPane() {
		return textPane;
	}

	public InfoTextPane getBottomLeftPanel() {
		return statsPanel;
	}

	public JList<Option> getOptionList() {
		return optionList;
	}

	public JTextField getOptionTextInput() {
		return optionTextInput;
	}

	public OptionTextInputKeyListener getOptionTextInputKeyListener() {
		return optionTextInputKeyListener;
	}

	// public JPanel getOptionCardPanel() {
	// return optionCardPanel;
	// }

	public TotemPanel getLeftTotemPanel() {
		return leftTotemPanel;
	}

	public TotemPanel getRightTotemPanel() {
		return rightTotemPanel;
	}

	public LocalMapPanel getLocalMapPanel() {
		return localMapPanel;
	}

}
